package main

import "fmt"

type Phone interface {
	call()
}

type MiPhone struct {
}

func (miPhone MiPhone) call() {
	fmt.Println("I am miPhone, I can call you!")
}

type IPhone struct {
}

func (iPhone IPhone) call() {
	fmt.Println("I am iPhone, I can call you!")
}

func main() {
	var phone Phone

	phone = new(MiPhone)
	phone.call()

	phone = new(IPhone)
	phone.call()

	var iphone IPhone
	fmt.Println(iphone)
	iphone.call()

	desc(1)
	desc("1")
	desc(phone)
	assert(1)
	assert("1")
	findType(1)
	findType("1")
	findType(phone)
}

func desc(i interface{}) {
	fmt.Printf("Type=%T, Value=%v \n", i, i)
}

func assert(i interface{}) {
	v, ok := i.(int)
	fmt.Println(v, ok)
}

func findType(i interface{}) {
	switch i.(type) {
	case string:
		fmt.Printf("Type=%T, Value=%v \n", i, i.(string))
	case int:
		fmt.Printf("Type=%T, Value=%v \n", i, i)
	default:
		fmt.Printf("findType() happen error. Type=%T, Value=%v \n", i, i)
	}
}


